package system

import (
	"context"
	"fmt"
	"gf-assistant/internal/common/consts"
	"gf-assistant/internal/common/factory"
	"gf-assistant/internal/common/util"
	"gf-assistant/internal/system/parameter"
	"github.com/gogf/gf/v2/util/gconv"
	"reflect"
	"strings"
)

type UserService struct {
	userDao string
}

func init() {
	userService := UserService{
		userDao: "system.UserDao",
	}
	factory.Put(reflect.TypeOf(userService).String(), &userService)
}
func (s *UserService) GetUserDao() *UserDao {
	return factory.Get(s.userDao).(*UserDao)
}
func (s *UserService) GetUser(ctx context.Context, req *parameter.GetUserReq) (res *parameter.GetUserRes) {
	return s.GetUserDao().GetUser(ctx, req)
}

func (s *UserService) ListUser(ctx context.Context, req *parameter.ListUserReq) (res *parameter.ListUserRes) {
	if req.Page <= 1 {
		req.Page = 1
	}
	if req.Size == 0 {
		req.Size = 10
	}
	users := s.GetUserDao().ListUser(ctx, req)
	count := s.GetUserDao().CountUser(ctx, req)
	res = &parameter.ListUserRes{
		Total:  count,
		Detail: users,
	}
	return res
}

// SaveUser  创建成员
func (s *UserService) SaveUser(ctx context.Context, req *parameter.SaveUserReq) (res *parameter.SaveUserRes) {
	if req.UserId == 0 && len(req.Password) == 0 {
		req.Password = "abcd.1234" //页面未填写密码时，提供默认密码：abcd.1234
	}
	if len(req.Password) > 0 {
		pwdSalt := util.Charset(7)
		req.SetPwdSalt(pwdSalt)
		req.Password = util.EncryptHash256(req.GetPwdSalt(), req.Password)
	}
	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetUserDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("账号已经存在")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()

	loginUserDO := s.GetUserDao().GetUserByUserName(ctx, strings.TrimSpace(req.UserName))
	if loginUserDO == nil && req.UserId == 0 {
		// 表示新增账号，判断账号是否存在
		if loginUserDO != nil {
			panic("账号已存在！")
		}
		res, err = s.GetUserDao().CreateUser(tx, req)
	} else {
		if loginUserDO != nil && loginUserDO.UserId != req.UserId {
			panic("账号已存在！")
		}
		res, err = s.GetUserDao().UpdateUser(tx, req)
	}
	return res
}

func (s *UserService) DeleteUser(ctx context.Context, req *parameter.DeleteUserReq) (res *parameter.DeleteUserRes) {
	if req.UserId == 0 {
		panic("用户ID必填")
	}
	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetUserDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("账号删除失败")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	s.GetUserDao().DeleteUser(tx, req)
	return res
}

// CheckUserNameUnique 检测给定的用户名是否唯一
func (s *UserService) checkUserNameUnique(ctx context.Context, userName string) string {
	res := s.GetUserDao().GetUserByUserName(ctx, userName)
	if res != nil {
		return fmt.Sprintf(`用户名"%s"已被占用`, userName)
	}
	return ""
}
func (s *UserService) GetUserPermission(ctx context.Context, req *parameter.GetUserPermissionReq) *parameter.GetUserPermissionRes {
	roleInfos := s.GetUserDao().GetUserPermission(ctx, req)
	for _, v := range roleInfos {
		v.Checked = gconv.Bool(v.AuthState)
		v.Spread = true
	}
	return &parameter.GetUserPermissionRes{
		Detail: roleInfos,
	}
}
func (s *UserService) AuthUserRole(ctx context.Context, req *parameter.AuthUserRoleReq) (res *parameter.AuthUserRoleRes) {
	req.SetOperatorId(gconv.Uint(ctx.Value(consts.ContextKeyUserId)))
	//开启事务
	tx, err := s.GetUserDao().DB().Begin(ctx)
	defer func() {
		if err != nil {
			_ = tx.Rollback()
			panic("授权失败")
		} else {
			err := tx.Commit()
			if err != nil {
				return
			}
		}
	}()
	s.GetUserDao().SaveUserRole(tx, req.UserId, req.RoleIds, req.GetOperatorId())
	return res
}
